package com.uye.framework.command;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import com.uye.framework.dto.IJSONRequest;
import com.uye.framework.dto.IJSONResponse;
import com.uye.framework.exception.CommandNotReadyForExecutionException;
import com.uye.framework.exception.InternalServerException;

/**
 * A unit of transactional work. Meant to react to JSONRequests by processing
 * the inputs and replying back with a JSONResponse.
 * 
 * @author uye
 */
public abstract class BaseStatefulJSONCommand<T extends IJSONRequest> extends BaseStatefulCommand<T> {

	private HttpServletRequest httpServletRequest;
	private HttpServletResponse httpServletResponse;
	private Class<T> requestClass;
	private boolean initedStatus = false;

	/**
	 * Declaring a default constructor to ensure Java Beans compliance.
	 */
	public BaseStatefulJSONCommand() {
	}

	/**
	 * Initialization logic. Extending classes should implement
	 * their own initialization logic but should at least call
	 * this one to mark the command as ready for execution.
	 * @param httpServletRequest
	 * @param httpServletResponse
	 * @param jsonRequest
	 * @param serviceName
	 */
	public void initialize(HttpServletRequest httpServletRequest,
			HttpServletResponse httpServletResponse) {

		this.httpServletRequest = httpServletRequest;
		this.httpServletResponse = httpServletResponse;
		initedStatus = true;
	}

	/**
	 * {@inheritDoc}
	 */
	public void checkReadyForExecution()
			throws CommandNotReadyForExecutionException {
		super.checkReadyForExecution();
		if (!initedStatus) {
			throw new CommandNotReadyForExecutionException(getModel().getServiceName(),
					this.getClass().getCanonicalName()
							+ " model has not been initialized.");
		}
	}

	public void setHttpServletRequest(HttpServletRequest httpServletRequest) {
		this.httpServletRequest = httpServletRequest;
	}

	public HttpServletRequest getHttpServletRequest() {
		return httpServletRequest;
	}

	public void setHttpServletResponse(HttpServletResponse httpServletResponse) {
		this.httpServletResponse = httpServletResponse;
	}

	public HttpServletResponse getHttpServletResponse() {
		return httpServletResponse;
	}

	public void sendResponse(IJSONResponse response)
			throws InternalServerException {
		JSONObject json = JSONObject.fromObject(response);
		try {
			json.write(httpServletResponse.getWriter());
		} catch (IOException e) {
			throw new InternalServerException(getModel().getServiceName(),"Could not send the response to the client.",e);
		}
	}

	public void setRequestModelClass(Class<T> requestClass) {
		this.requestClass = requestClass;
	}

	public Class<T> getRequestModelClass() {
		return requestClass;
	}

}
